iT邦幫忙

2023 iThome 鐵人賽

DAY 8
0
自我挑戰組

重新複習JavaScript系列 第 8

[Day -8] 函式(function)

  • 分享至 

  • xImage
  •  

我們在介紹data type時有提到,所有基本型別 (Primitives) 以外的值都是物件。

物件我們前面介紹了object 跟 array,現在要來介紹function了。

但在進入主題前,先讓我們認識兩個名詞:Expressions(表達式) 跟 Statements(陳述句)

Expressions(表達式)

表達式是產生值的代碼(An expression is a unit of code that results in a value.)

在JavaScript中,任何的expressions 都會創造一個值,但這個個值不一定會要在變數裡面。

例子:

Imgur

在瀏覽器的 console 中輸入 a = 3 時,它會直接回傳 3 這個值;輸入 2 + 3 的時候,它會直接回傳 5;輸入 a = { } 的時候,它會回傳一個為物件的值。這種輸入一段程式後,會直接取得回傳一個值的程式內容,我們就稱為 Expressions。

簡單來說:只要你輸入的那串程式執行後能直接回傳一個值,那麼它就是個 expression。

Statements(陳述句)

Statements是程式語言中的基本指令或命令,它們代表了一個完整的操作或行為。特徵為不會回傳一個結果 。

只用說的可能不好理解,我們直接用code來說

if (a === 3) {
  console.log('Hello');
}

這是一段陳述句(Statements),因為它不會直接回傳一個值,所以我們不能將它指定為一個變數:

// ❌ 錯誤寫法
var b = if (a === 3) {
  console.log('Hello');
}

基本結構

函式最基本的用途,是把會重覆使用的程式碼封裝起來,以便可以在需要的時候拿出來使用。

以下是一個函式的基本寫法:

function greet() {
  console.log('Hello');
}

function 是關鍵字。

greet 是函式名稱。

()內會放參數(parameters)。

{}內就是函式主體。

而當我們要使用函式就要使用「調用 (invoke)」。

function greet() {
  console.log('Hello');
}

greet() // Hello

First class functions(一級函式)

在JavaScript裡,函式的特性可不僅僅只是“把會重覆使用的程式碼封裝起來”而已,它還可以做出任何你對其他型別(Objects, String, Boolean, Numbers)也做得到事。

例如:將 Function 指定成一個變數,帶入另一個函式中、可以在一個 function 中回傳另一個 function、function 跟物件一樣有屬性(property)等等 。

那為什麼我們會說:In JavaScript, functions are objects.

function就像其他object一樣,他會儲存在記憶體中,並且有兩個特殊的部分:name 和 code。

  • Name:function 的名稱是可有可無的,它可以是一個匿名函式(anonymous function)
  • code:可以透過 () 來加以執行(invoke)。

看下面的範例:

function greet() {
  console.log('Hello');
}

greet.language = 'English';
greet();
console.log(greet.language);

輸出:

Hello
English

因為 function 可以當作物件來使用,所以可以直接用.來建立該物件的屬性和值,屬性的名稱為 language,值為 English。

當我今天要呼叫這個function,只要打該函式的名稱,後面接上括號 () 就可以去執行該函式

這樣的例子說明了,function只是一種特殊的物件,它可以被當作物件來使用。

Function Expressions 和 Function Statements

既然我們知道了在 JavaScript 中,Function 就是物件的一種,所以我們可以透過 Expression 或 Statements 的方式來操作它。

Function Statements

function greet() {
  console.log('Hi');
}

剛剛我們有說到,在JavaScript中function 就是物件,所以用物件的概念來理解函式的話,這個函式屬性 name 的值是 greeting,這個函式 code 屬性的值為 console.log(‘hi’)。

Imgur

當我們要執行這個函式的時候,只要輸入 greet() 就可以了。

而Function Statements 的特色在於,它在程式執行的最開始,該函式就會透過 hoisting先被儲存在記憶體中,因此我們可以在一開始就呼叫function 而不會出現錯誤:

greet();   // 'Hi'
function greet() {
  console.log('Hi');
}

Function Expressions

var anonymousGreet = function() {
  console.log('hi');
};

function(){ … } 這段就是 Function Expression,現在我們則把這個函式表達式的值存在 anonymousGreet 這個變數內。

剛剛我們有提到JavaScript中的function 就是物件,因此在這個範例,我們從物件的角度來看function:

Imgur

我們先建立了一個function,但這個function的 name 屬性並沒有給它值,之所以可以這麼做是因為,我們在 function expression 前面已經把它指定到一個變數(anonymousGreet),所以可以直接用這個變數名稱來指稱這個函式。對於這種 name 屬性沒有值的function,就叫做匿名函式(anonymous function 或 function literal)

同樣的要執行它也只需再變數名稱後加上()就可以了。

但這邊要特別注意,跟Function Statements 不同的是,我們不可以在還沒宣告變數時就呼叫他:

// ❌ 錯誤寫法
anonymousGreet(); 

const anonymousGreet = function() {
  console.log('Hello');
};

因為在一開始執行程式初期,只會先建立並儲存變數名稱到記憶體中,但程式內容不會一併儲存進去(這時候 anonymousGreet 的值會是 undefined),關於這個的底層原理會在之後的章節說明。

callback function

最後我們要來談談callback function。

我們建立了一個function,如下:

function log(a) {
  console.log(a);
}

因為我們有設定參數,所以這時候我們呼叫這個function時,就必須要給參數,給參數的方式有兩個:

// 方法1
const b = 3;
log(b);
// 方法2
log(3)

兩個的方法輸出都會是3。只是一個是用變數裝,一個是直接把值放到參數中。

那如果我要放的是一個function並執行呢?也是可以的

function log(a) {
  a();
}

var anonymousGreet = function() {
  console.log('Hi');
};

log(anonymousGreet);

或是我們可以寫的更簡化些:

function log(a) {
  a();
}

log(function() {
  console.log('Hi');
});

這樣,就可以在不用建立函式的情況下,直接去執行一個匿名函式。

由於 JavaScript 非同步的特性,若想要確保程式執行的順序,常常會使用到回呼函式(callback function)這種方式,它內部的做法其實也就是把函式傳入另一個函式中去呼叫。


我大概是第一位資料型別可以水這麼多天的人吧XDDD

明天還有一篇關於Function的底層原理,加上這篇就5篇了。

還好這是自我挑戰組XDDD


上一篇
[Day -7] 資料型別(data types)(3)
下一篇
[Day -9] 了解function底層運作邏輯
系列文
重新複習JavaScript30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言